home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!cs.odu.edu!Amiga-Request
- From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
- Newsgroups: comp.sources.amiga
- Subject: v90i021: make - a re-implementation of the UNIX make utility, Part02/02
- Message-ID: <11028@xanth.cs.odu.edu>
- Date: 17 Jan 90 23:17:09 GMT
- Sender: tadguy@cs.odu.edu
- Reply-To: Olaf 'Rhialto' Seibert <U211344@HNYKUN11.BITNET>
- Lines: 617
- Approved: tadguy@cs.odu.edu (Tad Guy)
-
- Submitted-by: Olaf 'Rhialto' Seibert <U211344@HNYKUN11.BITNET>
- Posting-number: Volume 90, Issue 021
- Archive-name: unix/make/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 2)."
- # Contents: make.c
- # Wrapped by tadguy@xanth on Wed Jan 17 18:16:24 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'make.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'make.c'\"
- else
- echo shar: Extracting \"'make.c'\" \(11870 characters\)
- sed "s/^X//" >'make.c' <<'END_OF_FILE'
- X/*
- X * Do the actual making for make
- X */
- X
- X#include <stdio.h>
- X#ifdef unix
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/errno.h>
- X#endif
- X#ifdef eon
- X#include <sys/stat.h>
- X#include <sys/err.h>
- X#endif
- X#ifdef os9
- X#include <time.h>
- X#include <os9.h>
- X#include <modes.h>
- X#include <direct.h>
- X#include <errno.h>
- X#endif
- X#ifdef amiga
- X#include <ctype.h>
- X#include <errno.h>
- X#include <libraries/dosextens.h>
- X#include <exec/memory.h>
- X#include <exec/io.h>
- X#include <exec/ports.h>
- X#include <functions.h>
- X#undef TRUE /*OIS*0.80*/
- X#undef FALSE /*OIS*0.80*/
- X/*#define ACTION_SET_DATE 34L /*OIS*0.80*/
- X#endif
- X#include "h.h"
- X
- X
- X
- X/*
- X * Exec a shell that returns exit status correctly (/bin/esh).
- X * The standard EON shell returns the process number of the last
- X * async command, used by the debugger (ugg).
- X * [exec on eon is like a fork+exec on unix]
- X */
- Xint
- Xdosh(string, shell)
- X char *string;
- X char *shell;
- X{
- X int number;
- X
- X#ifdef amiga
- X char *av[3], *s, *p;
- X int i;
- X
- X fflush(stdout); /*OIS*0.80*/
- X if ((p = s = malloc((unsigned) strlen(string) + 1)) == NULL)
- X fatal("No memory for command '%s'", string);
- X strcpy(p, string); /* make a copy of the string */
- X i = 0;
- X av[0] = gettok(&p); /* get first argument */
- X av[1] = p; /* get rest of command line */
- X av[2] = NULL;
- X if (fexecv(av[0], av) == -1)
- X fatal("couldn't execute command '%s', error return %02x\n",
- X av[0], errno);
- X number = wait();
- X free(s);
- X return number;
- X#endif
- X
- X#ifdef unix
- X return system(string);
- X#endif
- X#ifdef eon
- X return ((number = execl(shell, shell, "-c", string, 0)) == -1) ?
- X -1 : /* couldn't start the shell */
- X wait(number); /* return its exit status */
- X#endif
- X#ifdef os9
- X int status, pid;
- X
- X strcat(string, "\n");
- X if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
- X return -1; /* Couldn't start a shell */
- X do {
- X if ((pid = wait(&status)) == -1)
- X return -1; /* child already died!?!? */
- X } while (pid != number);
- X
- X return status;
- X#endif
- X}
- X
- X
- X/*
- X * Do commands to make a target
- X */
- Xvoid
- Xdocmds1(np, lp)
- X struct name *np;
- X struct line *lp;
- X{
- X bool ssilent;
- X bool signore;
- X int estat;
- X register char *q;
- X register char *p;
- X char *shell;
- X register struct cmd *cp;
- X#ifdef amiga
- X long SetSignal();
- X#endif
- X
- X#ifndef amiga
- X if (*(shell = getmacro("SHELL")) == '\0')
- X#ifdef eon
- X shell = ":bin/esh";
- X#endif
- X#ifdef unix
- X shell = "/bin/sh";
- X#endif
- X#ifdef os9
- X shell = "shell";
- X#endif
- X#else /* for amiga */
- X shell = NULL;
- X#endif
- X
- X for (cp = lp->l_cmd; cp; cp = cp->c_next) {
- X strcpy(str1, cp->c_cmd);
- X expand(str1);
- X q = str1;
- X ssilent = silent;
- X signore = ignore;
- X while ((*q == '@') || (*q == '-')) {
- X if (*q == '@') /* Specific silent */
- X ssilent = TRUE;
- X else /* Specific ignore */
- X signore = TRUE;
- X q++; /* Not part of the command */
- X }
- X
- X if (!domake)
- X ssilent = 0;
- X
- X if (!ssilent)
- X fputs(" ", stdout);
- X
- X for (p = q; *p; p++) {
- X if (*p == '\n' && p[1] != '\0') {
- X *p = ' ';
- X if (!ssilent)
- X fputs("\\\n", stdout);
- X } else if (!ssilent)
- X putchar(*p);
- X }
- X if (!ssilent)
- X putchar('\n');
- X
- X if (domake) { /* Get the shell to execute it */
- X if ((estat = dosh(q, shell)) != 0) {
- X if (estat == -1)
- X fatal("Couldn't execute %s", shell);
- X else {
- X printf("%s: Error code %d", myname, estat);
- X if (signore)
- X fputs(" (Ignored)\n", stdout);
- X else {
- X putchar('\n');
- X if (!(np->n_flag & N_PREC))
- X if (unlink(np->n_name) == 0)
- X printf("%s: '%s' removed.\n", myname, np->n_name);
- X exit(estat);
- X }
- X }
- X }
- X#ifdef amiga
- X if ((SetSignal(0L, SIGBREAKF_CTRL_D) & SIGBREAKF_CTRL_D) != 0) {
- X fatal("Abort due to ^D"); /*OIS*0.80*/
- X }
- X#endif
- X }
- X }
- X}
- X
- X
- Xdocmds(np)
- X struct name *np;
- X{
- X register struct line *lp;
- X
- X
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X docmds1(np, lp);
- X}
- X
- X
- X#ifdef os9
- X/*
- X * Some stuffing around to get the modified time of a file
- X * in an os9 file system
- X */
- Xgetmdate(fd, tbp)
- X struct sgtbuf *tbp;
- X{
- X struct registers regs;
- X static struct fildes fdbuf;
- X
- X
- X regs.rg_a = fd;
- X regs.rg_b = SS_FD;
- X regs.rg_x = &fdbuf;
- X regs.rg_y = sizeof(fdbuf);
- X
- X if (_os9(I_GETSTT, ®s) == -1) {
- X errno = regs.rg_b & 0xff;
- X return -1;
- X }
- X if (tbp) {
- X _strass(tbp, fdbuf.fd_date, sizeof(fdbuf.fd_date));
- X tbp->t_second = 0; /* Files are only acurate to mins */
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * Kludge routine to return an aproximation of how many
- X * seconds since 1980. Dates will be in order, but will not
- X * be lineer
- X */
- Xtime_t
- Xcnvtime(tbp)
- X struct sgtbuf *tbp;
- X{
- X long acc;
- X
- X
- X acc = tbp->t_year - 80; /* Baseyear is 1980 */
- X acc = acc * 12 + tbp->t_month;
- X acc = acc * 31 + tbp->t_day;
- X acc = acc * 24 + tbp->t_hour;
- X acc = acc * 60 + tbp->t_minute;
- X acc = acc * 60 + tbp->t_second;
- X
- X return acc;
- X}
- X
- X
- X/*
- X * Get the current time in the internal format
- X */
- Xtime(tp)
- X time_t *tp;
- X{
- X struct sgtbuf tbuf;
- X
- X
- X if (getime(&tbuf) < 0)
- X return -1;
- X
- X if (tp)
- X *tp = cnvtime(&tbuf);
- X
- X return 0;
- X}
- X#endif
- X
- X
- X/*
- X * Get the modification time of a file. If the first
- X * doesn't exist, it's modtime is set to 0.
- X */
- Xvoid
- Xmodtime(np)
- X struct name *np;
- X{
- X#ifdef unix
- X struct stat info;
- X int fd;
- X
- X
- X if (stat(np->n_name, &info) < 0) {
- X if (errno != ENOENT)
- X fatal("Can't open %s; error %d", np->n_name, errno);
- X
- X np->n_time = 0L;
- X } else
- X np->n_time = info.st_mtime;
- X#endif
- X#ifdef eon
- X struct stat info;
- X int fd;
- X
- X
- X if ((fd = open(np->n_name, 0)) < 0) {
- X if (errno != ER_NOTF)
- X fatal("Can't open %s; error %02x", np->n_name, errno);
- X
- X np->n_time = 0L;
- X } else if (getstat(fd, &info) < 0)
- X fatal("Can't getstat %s; error %02x", np->n_name, errno);
- X else
- X np->n_time = info.st_mod;
- X
- X close(fd);
- X#endif
- X#ifdef os9
- X struct sgtbuf info;
- X int fd;
- X
- X
- X if ((fd = open(np->n_name, 0)) < 0) {
- X if (errno != E_PNNF)
- X fatal("Can't open %s; error %02x", np->n_name, errno);
- X
- X np->n_time = 0L;
- X } else if (getmdate(fd, &info) < 0)
- X fatal("Can't getstat %s; error %02x", np->n_name, errno);
- X else
- X np->n_time = cnvtime(&info);
- X
- X close(fd);
- X#endif
- X#ifdef amiga
- X struct FileInfoBlock *fib;
- X struct FileLock *myLock;
- X long ioErr;
- X
- X fib = (struct FileInfoBlock *) malloc((unsigned) sizeof(struct FileInfoBlock));
- X if ((myLock = Lock(np->n_name, ACCESS_READ)) == NULL) {
- X if ((ioErr = IoErr()) != ERROR_OBJECT_NOT_FOUND)
- X fatal("Can't Lock '%s'; error %3ld", np->n_name, ioErr);
- X np->n_time = 0L;
- X } else if (!Examine(myLock, fib)) {
- X UnLock(myLock);
- X fatal("Can't Examine '%s'; error %3ld", np->n_name, IoErr());
- X } else {
- X np->n_time = fib->fib_Date.ds_Tick/TICKS_PER_SECOND +
- X 60*fib->fib_Date.ds_Minute + 86400*fib->fib_Date.ds_Days;
- X UnLock(myLock);
- X }
- X free((char *) fib);
- X#endif
- X
- X}
- X
- X#ifdef amiga
- Xchar *
- Xnametail(name)
- Xregister char *name;
- X{
- X register char *tail;
- X
- X if ((tail = index(name, ':')) == NULL) /* strip device name */
- X tail = name;
- X if ((name = rindex(tail, '/')) == NULL) /* strip directories */
- X name = tail;
- X
- X return name;
- X}
- X#endif
- X
- X
- X/*
- X * Update the mod time of a file to now.
- X */
- Xvoid
- Xtouch(np)
- X struct name *np;
- X{
- X char c;
- X int fd;
- X
- X
- X if (!domake || !silent)
- X printf(" touch(%s)\n", np->n_name);
- X
- X if (domake) {
- X#ifdef unix
- X long a[2];
- X
- X a[0] = a[1] = time(0);
- X if (utime(np->n_name, &a[0]) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X#endif
- X#ifdef eon
- X if ((fd = open(np->n_name, 0)) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X else {
- X uread(fd, &c, 1, 0);
- X uwrite(fd, &c, 1);
- X }
- X close(fd);
- X#endif
- X#ifdef os9
- X /*
- X * Strange that something almost as totally useless as this is easy
- X * to do in os9!
- X */
- X if ((fd = open(np->n_name, S_IWRITE)) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X close(fd);
- X#endif
- X#ifdef amiga
- X struct MsgPort *task;
- X ULONG dateStamp[3];
- X struct FileLock *lock, *plock;
- X UBYTE *bcplstring;
- X
- X if(!(bcplstring = (UBYTE *)AllocMem(64L, MEMF_PUBLIC)))
- X fatal("Can't get 64 bytes for bcplstring");
- X if(!(task=(struct MsgPort *)DeviceProc(np->n_name))) {
- X printf("%s: can't get MsgPort for '%s'\n", myname, np->n_name);
- X goto abort;
- X }
- X if(!(lock = Lock(np->n_name, SHARED_LOCK))) {
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X goto abort;
- X }
- X plock = ParentDir(lock);
- X UnLock(lock);
- X
- X /* Strip pathnames first */
- X strcpy((bcplstring + 1), nametail(np->n_name));
- X *bcplstring = strlen(bcplstring + 1);
- X
- X dos_packet(task, ACTION_SET_DATE, NULL, plock, (ULONG)bcplstring >> 2,
- X (ULONG) DateStamp(dateStamp), 0L, 0L, 0L);
- X
- X UnLock(plock);
- Xabort:
- X FreeMem((void *) bcplstring, 64L);
- X#endif
- X }
- X}
- X
- X/*
- X * Recursive routine to make a target.
- X */
- Xint
- Xmake(np, level)
- X struct name *np;
- X int level;
- X{
- X register struct depend *dp;
- X register struct line *lp;
- X register struct depend *qdp;
- X time_t dtime = 1, time();
- X bool didsomething = 0;
- X char * basename = (char *) 0;
- X char * inputname = (char *) 0;
- X
- X
- X if (np->n_flag & N_DONE)
- X return 0;
- X
- X if (!np->n_time)
- X modtime(np); /* Gets modtime of this file */
- X
- X if (rules) {
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X if (lp->l_cmd)
- X break;
- X if (!lp)
- X dyndep(np, &basename, &inputname);
- X }
- X if (!(np->n_flag & N_TARG) && np->n_time == 0L)
- X fatal("Don't know how to make %s", np->n_name);
- X
- X for (qdp = (struct depend *) 0, lp = np->n_line; lp; lp = lp->l_next) {
- X for (dp = lp->l_dep; dp; dp = dp->d_next) {
- X make(dp->d_name, level + 1);
- X if (np->n_time < dp->d_name->n_time)
- X qdp = newdep(dp->d_name, qdp);
- X dtime = max(dtime, dp->d_name->n_time);
- X }
- X if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) {
- X make1(np, lp, qdp, basename, inputname); /* free()'s qdp */
- X dtime = 1;
- X qdp = (struct depend *) 0;
- X didsomething++;
- X }
- X }
- X
- X np->n_flag |= N_DONE;
- X
- X if (quest) {
- X long t;
- X
- X t = np->n_time;
- X time(&np->n_time);
- X if (basename)
- X free(basename);
- X
- X return t < dtime;
- X } else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) {
- X make1(np, (struct line *)0, qdp, basename, inputname); /* free()'s qdp */
- X time(&np->n_time);
- X } else if (level == 0 && !didsomething)
- X printf("%s: '%s' is up to date\n", myname, np->n_name);
- X
- X if (basename)
- X free(basename);
- X
- X return 0;
- X}
- X
- X
- Xmake1(np, lp, qdp, basename, inputname)
- X register struct depend *qdp;
- X struct line *lp;
- X struct name *np;
- X char *basename;
- X char *inputname;
- X{
- X register struct depend *dp;
- X
- X
- X if (dotouch)
- X touch(np);
- X else {
- X strcpy(str1, "");
- X if (!basename)
- X basename = str1;
- X setmacro("*", basename); /* $* = file */
- X if (!inputname)
- X inputname = str1;
- X setmacro("<", inputname); /* $< = path/file.c or file.c */
- X for (dp = qdp; dp; dp = qdp) {
- X if (strlen(str1))
- X strcat(str1, " ");
- X strcat(str1, dp->d_name->n_name);
- X qdp = dp->d_next;
- X free(dp);
- X }
- X setmacro("?", str1); /* $? = file.c file1.h file2.h */
- X setmacro("@", np->n_name); /* $@ = file.o */
- X if (lp) /* lp set if doing a :: rule */
- X docmds1(np, lp);
- X else
- X docmds(np);
- X }
- X}
- X#ifdef amiga
- X/*
- X * Replace the Aztec-provided time function with one which returns something
- X * easy to find and compare, namely the number of seconds since the Amiga's
- X * reference date. This is the same thing returned by modtime() above.
- X */
- Xtime_t
- Xtime(v)
- X time_t *v;
- X{
- X long t[3];
- X
- X DateStamp(t);
- X t[0] = t[2]/TICKS_PER_SECOND + 60*t[1] + 86400*t[0];
- X if (v)
- X *v = t[0];
- X return t[0];
- X}
- X#endif
- END_OF_FILE
- if test 11870 -ne `wc -c <'make.c'`; then
- echo shar: \"'make.c'\" unpacked with wrong size!
- fi
- # end of 'make.c'
- fi
- echo shar: End of archive 2 \(of 2\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to:
- amiga@cs.odu.edu
- or amiga@xanth.cs.odu.edu ( obsolescent mailers may need this address )
- or ...!uunet!xanth!amiga ( very obsolescent mailers need this address )
-
- Comments, questions, and suggestions s should be addressed to ``amiga-request''
- (only use ``amiga'' for submissions) at the above addresses.
-